Skip to content

Conversation

@luke-mino-altherr
Copy link
Contributor

@luke-mino-altherr luke-mino-altherr commented Dec 6, 2025

Summary

Adds a dropdown filter to the model browser that allows users to filter assets by ownership (All, My models, Public models), based on the is_immutable property.

Changes

  • Filter UI: Added ownership dropdown in AssetFilterBar.vue that only appears when user has uploaded models
  • Filter Logic: Implemented filterByOwnership function in useAssetBrowser.ts to filter by is_immutable property
  • i18n: Added translation strings for ownership filter options
  • Tests: Added comprehensive tests for ownership filtering in both composable and component test files

Review Focus

  • The ownership filter visibility logic correctly checks for mutable assets (!is_immutable)
  • Default filter value is 'all' to show all models initially
  • Filter integrates cleanly with existing file format and base model filters

🤖 Generated with Claude Code

┆Issue is synchronized with this Notion page by Unito

@luke-mino-altherr luke-mino-altherr added enhancement New feature or request area:models labels Dec 6, 2025
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Dec 6, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 6, 2025

📝 Walkthrough

Walkthrough

Adds ownership-based filtering to the asset browser: new i18n keys, an ownership SingleSelect shown when mutable assets exist, ownership filtering in the composable, fixture support for asset immutability, updated tests, and AssetBrowserModal wiring to pass all assets.

Changes

Cohort / File(s) Change Summary
Localization
src/locales/en/main.json
Added four ownership localization keys: ownership, ownershipAll, ownershipMyModels, ownershipPublicModels.
Asset Filter UI
src/platform/assets/components/AssetFilterBar.vue
Added conditional ownership SingleSelect (visible when mutable assets exist); introduced OWNERSHIP_OPTIONS, OwnershipOption, ownershipOptions; added ownership reactive state; extended exported FilterState to include ownership; included ownership in emitted filterChange; added optional allAssets prop and hasMutableAssets computed.
Asset Browser Filtering
src/platform/assets/composables/useAssetBrowser.ts
Added ownership to filters (default 'all'); implemented filterByOwnership and applied ownership filtering in the filteredAssets pipeline.
Fixtures
src/platform/assets/fixtures/ui-mock-assets.ts
Extended createAssetWithSpecificExtension signature to (extension: string, isImmutable?: boolean) and set asset.is_immutable when provided.
Asset Browser Modal
src/platform/assets/components/AssetBrowserModal.vue
Passed full asset list to AssetFilterBar via new all-assets prop binding (fetchedAssets).
Component Tests
tests-ui/platform/assets/components/AssetFilterBar.test.ts
Adjusted sort-control lookup; added tests for ownership filter visibility (no mutable / any mutable / mixed) and tests verifying emitted filterChange includes ownership and defaults to 'all'.
Composable Tests
tests-ui/platform/assets/composables/useAssetBrowser.test.ts
Extended tests and updateFilters payloads to include ownership ('all', 'my-models', 'public-models') and validated ownership-based filtering.
sequenceDiagram
  participant User
  participant AssetFilterBar
  participant AssetBrowserModal
  participant useAssetBrowser
  participant AssetStore

  User->>AssetFilterBar: selects Ownership option
  AssetFilterBar->>AssetBrowserModal: emit filterChange { ownership, sortBy, ... }
  AssetBrowserModal->>useAssetBrowser: updateFilters({ ownership, ... })
  useAssetBrowser->>AssetStore: read fetchedAssets / all assets
  useAssetBrowser->>useAssetBrowser: apply file-format, base-model, ownership filters
  useAssetBrowser-->>AssetBrowserModal: return filteredAssets
  AssetBrowserModal-->>User: render updated asset list
Loading

Possibly related PRs

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/model-modal-filter-by-ownership

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Dec 6, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 12/07/2025, 02:06:51 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Dec 6, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 12/07/2025, 02:15:16 AM UTC

📈 Summary

  • Total Tests: 495
  • Passed: 481 ✅
  • Failed: 0
  • Flaky: 4 ⚠️
  • Skipped: 10 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 472 / ❌ 0 / ⚠️ 4 / ⏭️ 10
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 0 / ⚠️ 0 / ⏭️ 0

🎉 Click on the links above to view detailed test results for each browser configuration.

@github-actions
Copy link

github-actions bot commented Dec 6, 2025

Bundle Size Report

Summary

  • Raw size: 17 MB baseline 17 MB — 🔴 +1.72 kB
  • Gzip: 3.38 MB baseline 3.38 MB — 🔴 +288 B
  • Brotli: 2.59 MB baseline 2.59 MB — 🔴 +145 B
  • Bundles: 97 current • 97 baseline • 37 added / 37 removed

Category Glance
Graph Workspace 🔴 +1.59 kB (978 kB) · App Entry Points 🔴 +125 B (3.2 MB) · Vendor & Third-Party ⚪ 0 B (8.56 MB) · Other ⚪ 0 B (3.81 MB) · Panels & Settings ⚪ 0 B (298 kB) · UI Components ⚪ 0 B (177 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.2 MB (baseline 3.2 MB) • 🔴 +125 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-CdTVwCwZ.js (new) 2.98 MB 🔴 +2.98 MB 🔴 +619 kB 🔴 +471 kB
assets/index-CNJVegdf.js (removed) 2.98 MB 🟢 -2.98 MB 🟢 -619 kB 🟢 -471 kB
assets/index-C5LwoASq.js (removed) 223 kB 🟢 -223 kB 🟢 -47.6 kB 🟢 -39.3 kB
assets/index-CaiSqTEp.js (new) 223 kB 🔴 +223 kB 🔴 +47.6 kB 🔴 +39.2 kB
assets/index-DMWlUgVM.js (new) 345 B 🔴 +345 B 🔴 +244 B 🔴 +230 B
assets/index-i2_w9ipF.js (removed) 345 B 🟢 -345 B 🟢 -244 B 🟢 -232 B

Status: 3 added / 3 removed

Graph Workspace — 978 kB (baseline 976 kB) • 🔴 +1.59 kB

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-B1gkRHi0.js (new) 978 kB 🔴 +978 kB 🔴 +189 kB 🔴 +144 kB
assets/GraphView-D17Bs9_z.js (removed) 976 kB 🟢 -976 kB 🟢 -189 kB 🟢 -144 kB

Status: 1 added / 1 removed

Views & Navigation — 6.54 kB (baseline 6.54 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-DvitM7q6.js (new) 6.54 kB 🔴 +6.54 kB 🔴 +2.14 kB 🔴 +1.9 kB
assets/UserSelectView-Z_UFG1vP.js (removed) 6.54 kB 🟢 -6.54 kB 🟢 -2.14 kB 🟢 -1.9 kB

Status: 1 added / 1 removed

Panels & Settings — 298 kB (baseline 298 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CreditsPanel-DCftrlFM.js (removed) 21.4 kB 🟢 -21.4 kB 🟢 -5.15 kB 🟢 -4.5 kB
assets/CreditsPanel-DT5Z7RN2.js (new) 21.4 kB 🔴 +21.4 kB 🔴 +5.15 kB 🔴 +4.5 kB
assets/KeybindingPanel-D4sMvz7y.js (new) 13.6 kB 🔴 +13.6 kB 🔴 +3.42 kB 🔴 +3.01 kB
assets/KeybindingPanel-D4ULAgh8.js (removed) 13.6 kB 🟢 -13.6 kB 🟢 -3.42 kB 🟢 -3.01 kB
assets/ExtensionPanel-BryPehiW.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.58 kB 🔴 +2.26 kB
assets/ExtensionPanel-nEV6mJlg.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.57 kB 🟢 -2.26 kB
assets/AboutPanel-Co0Ehyw7.js (removed) 9.16 kB 🟢 -9.16 kB 🟢 -2.46 kB 🟢 -2.21 kB
assets/AboutPanel-nfM0fuaP.js (new) 9.16 kB 🔴 +9.16 kB 🔴 +2.46 kB 🔴 +2.21 kB
assets/ServerConfigPanel-COwCHbiM.js (removed) 6.56 kB 🟢 -6.56 kB 🟢 -1.83 kB 🟢 -1.63 kB
assets/ServerConfigPanel-CTfexokj.js (new) 6.56 kB 🔴 +6.56 kB 🔴 +1.83 kB 🔴 +1.63 kB
assets/UserPanel-9SzrRfj3.js (removed) 6.23 kB 🟢 -6.23 kB 🟢 -1.72 kB 🟢 -1.51 kB
assets/UserPanel-HM8pulfg.js (new) 6.23 kB 🔴 +6.23 kB 🔴 +1.72 kB 🔴 +1.51 kB
assets/settings-BhbWhsRg.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BXTtSH4O.js 33.3 kB 33.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C9Pzn-NG.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CCy2fA_h.js 27.3 kB 27.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CQpqEFfl.js 26.6 kB 26.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DHcnxypw.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DhFTK9fY.js 25.1 kB 25.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DlT4t_ui.js 25.9 kB 25.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DRgSrIdD.js 24.2 kB 24.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-tjkeqiZq.js 21.1 kB 21.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 177 kB (baseline 177 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/Load3D.vue_vue_type_script_setup_true_lang-B5BOvY0E.js (removed) 53.9 kB 🟢 -53.9 kB 🟢 -8.52 kB 🟢 -7.32 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-D1zNew3Y.js (new) 53.9 kB 🔴 +53.9 kB 🔴 +8.52 kB 🔴 +7.31 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-CNkbGgnU.js (new) 48 kB 🔴 +48 kB 🔴 +10.3 kB 🔴 +8.97 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-DXASHIiv.js (removed) 48 kB 🟢 -48 kB 🟢 -10.3 kB 🟢 -8.97 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-Cr92-mkp.js (new) 46.9 kB 🔴 +46.9 kB 🔴 +10.5 kB 🔴 +9.17 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-Dq0jF4zY.js (removed) 46.9 kB 🟢 -46.9 kB 🟢 -10.5 kB 🟢 -9.17 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-B6SUKWg-.js (new) 12.9 kB 🔴 +12.9 kB 🔴 +3.37 kB 🔴 +2.98 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-CDXxjob2.js (removed) 12.9 kB 🟢 -12.9 kB 🟢 -3.37 kB 🟢 -2.97 kB
assets/ComfyQueueButton-C6Gj47Jp.js (removed) 8.44 kB 🟢 -8.44 kB 🟢 -2.48 kB 🟢 -2.21 kB
assets/ComfyQueueButton-DRTO9waa.js (new) 8.44 kB 🔴 +8.44 kB 🔴 +2.48 kB 🔴 +2.21 kB
assets/MediaTitle.vue_vue_type_script_setup_true_lang-DmXNBjTW.js (new) 897 B 🔴 +897 B 🔴 +503 B 🔴 +428 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-MSgs97zq.js (removed) 897 B 🟢 -897 B 🟢 -504 B 🟢 -472 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-BPGmgVoN.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-CFWrwaAG.js 2.04 kB 2.04 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-6ZIklFyS.js 2.26 kB 2.26 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-BpWfym2Q.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.83 kB 🟢 -1.58 kB
assets/keybindingService-lLp-leDd.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.58 kB
assets/audioService-6xWe6Upa.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +961 B 🔴 +822 B
assets/audioService-CxoNvQjU.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -961 B 🟢 -825 B
assets/serverConfigStore-L3qzi_1Z.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 removed

Utilities & Hooks — 2.94 kB (baseline 2.94 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-TYBLz4z7.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -652 B 🟢 -548 B
assets/audioUtils-yBVygA92.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +652 B 🔴 +549 B
assets/mathUtil-CTARWQ-l.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeFilterUtil-CXKCRJ-m.js 460 B 460 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

Vendor & Third-Party — 8.56 MB (baseline 8.56 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-DJFoH6N_.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-BZV8aGUB.js 3.98 MB 3.98 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-DUTcKlCc.js 1.96 MB 1.96 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-aR6ntw5X.js 1.37 MB 1.37 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-Cmu0_BY4.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-Bz22sFex.js 160 kB 160 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BZLod3g9.js 407 kB 407 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 3.81 MB (baseline 3.81 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/WidgetRecordAudio-6a_pzyT7.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.24 kB 🟢 -4.63 kB
assets/WidgetRecordAudio-DXHLvXd7.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.24 kB 🔴 +4.63 kB
assets/AudioPreviewPlayer-4AUzZvzh.js (new) 13.5 kB 🔴 +13.5 kB 🔴 +3.4 kB 🔴 +3.05 kB
assets/AudioPreviewPlayer-CCRXYumW.js (removed) 13.5 kB 🟢 -13.5 kB 🟢 -3.4 kB 🟢 -3.04 kB
assets/WidgetGalleria-Bf_Z_afF.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.44 kB 🟢 -1.3 kB
assets/WidgetGalleria-DzuRrCFv.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.45 kB 🔴 +1.31 kB
assets/WidgetColorPicker-B7J7pR32.js (removed) 3.41 kB 🟢 -3.41 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/WidgetColorPicker-DYk9r63F.js (new) 3.41 kB 🔴 +3.41 kB 🔴 +1.38 kB 🔴 +1.23 kB
assets/WidgetMarkdown-CpUtT4U_.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.28 kB 🔴 +1.12 kB
assets/WidgetMarkdown-DtTTbOWf.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.28 kB 🟢 -1.12 kB
assets/WidgetTextarea-BtbI6srv.js (new) 2.93 kB 🔴 +2.93 kB 🔴 +1.17 kB 🔴 +1.04 kB
assets/WidgetTextarea-rPildO77.js (removed) 2.93 kB 🟢 -2.93 kB 🟢 -1.17 kB 🟢 -1.05 kB
assets/WidgetAudioUI-CU71O_iF.js (removed) 2.85 kB 🟢 -2.85 kB 🟢 -1.16 kB 🟢 -1.05 kB
assets/WidgetAudioUI-D0hL4I4R.js (new) 2.85 kB 🔴 +2.85 kB 🔴 +1.17 kB 🔴 +1.06 kB
assets/WidgetInputText-DmuQyG5x.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +916 B 🔴 +854 B
assets/WidgetInputText-DSBhYeBa.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -915 B 🟢 -851 B
assets/MediaImageBottom-BqZxrn3E.js (new) 1.57 kB 🔴 +1.57 kB 🔴 +743 B 🔴 +649 B
assets/MediaImageBottom-CGHRca_8.js (removed) 1.57 kB 🟢 -1.57 kB 🟢 -742 B 🟢 -645 B
assets/MediaAudioBottom-BGgYbgH2.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -740 B 🟢 -659 B
assets/MediaAudioBottom-IGGoK-R7.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +742 B 🔴 +657 B
assets/MediaVideoBottom-CBRDHq3Q.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +741 B 🔴 +656 B
assets/MediaVideoBottom-CR5yQ2ZG.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -740 B 🟢 -655 B
assets/Media3DBottom-A5-kHFOj.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -734 B 🟢 -653 B
assets/Media3DBottom-DbSmzrZX.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +731 B 🔴 +652 B
assets/Media3DTop-BZRCvILO.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +766 B 🔴 +653 B
assets/Media3DTop-ZQsZfvG8.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -765 B 🟢 -651 B
assets/WidgetSelect-BHzpe_cf.js (new) 655 B 🔴 +655 B 🔴 +343 B 🔴 +290 B
assets/WidgetSelect-YeXwWDLL.js (removed) 655 B 🟢 -655 B 🟢 -344 B 🟢 -288 B
assets/WidgetInputNumber--pHq7r9z.js (new) 595 B 🔴 +595 B 🔴 +331 B 🔴 +277 B
assets/WidgetInputNumber-CQrKAjiR.js (removed) 595 B 🟢 -595 B 🟢 -329 B 🟢 -276 B
assets/Load3D-DLd-BbtZ.js (removed) 424 B 🟢 -424 B 🟢 -266 B 🟢 -224 B
assets/Load3D-DzblC4dP.js (new) 424 B 🔴 +424 B 🔴 +267 B 🔴 +223 B
assets/WidgetLegacy-BJbEnyIY.js (new) 364 B 🔴 +364 B 🔴 +238 B 🔴 +195 B
assets/WidgetLegacy-KHHuksnz.js (removed) 364 B 🟢 -364 B 🟢 -237 B 🟢 -201 B
assets/commands-_s-RvhJR.js 13.6 kB 13.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BuUILW6P.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BV4R6fLx.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BWp4HdfU.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CLwPdnT6.js 14.2 kB 14.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CWMchBmd.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DazTQhtc.js 12.9 kB 12.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DmWrOe93.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwiH7Kr6.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-mS3LCNPn.js 14.5 kB 14.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B1JflQcI.js 72.2 kB 72.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B2lyXe48.js 114 kB 114 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B9XEQ-pc.js 94 kB 94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BErKFzc-.js 73.1 kB 73.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bf7Tze-u.js 83.4 kB 83.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BhGMcO4Q.js 84.3 kB 84.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CPZUloNQ.js 99 kB 99 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cw9RZWRY.js 89 B 89 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Dva0z-T2.js 86.5 kB 86.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-un0K9wDS.js 81.8 kB 81.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-BPDWO8-i.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-BtY1hGDO.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-ehTZdDBw.js 2.76 kB 2.76 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-8e6QYQW0.js 283 kB 283 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-A_9dx4yn.js 304 kB 304 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BbD3HDi7.js 307 kB 307 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BOJhIPft.js 369 kB 369 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bw_Jitw_.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-C-Pw33mW.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-ChLyG0UJ.js 285 kB 285 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CUVPxA4l.js 342 kB 342 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Dx5Y4xrW.js 310 kB 310 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-JqO5mNmW.js 306 kB 306 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-j6EYUdOM.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-D5bj5c8l.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-DPJMnc2A.js 1.58 kB 1.58 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 17 added / 17 removed

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests-ui/platform/assets/composables/useAssetBrowser.test.ts (1)

248-255: FilterState updates are consistent; align sortBy value with implementation

Including ownership: 'all' in the various updateFilters calls keeps these tests in sync with the extended FilterState and with the composable’s default behavior.

One small clean‑up: in the “sorts assets by name” test you still use sortBy: 'name', while useAssetBrowser’s switch handles 'name-asc' | 'name-desc' | 'recent' | 'popular' and falls back to 'name-asc' for unknown values. To avoid relying on the fallback branch, consider updating that test to use 'name-asc' explicitly.

Also applies to: 285-290, 340-345, 365-370

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cde49d5 and 8705f77.

📒 Files selected for processing (6)
  • src/locales/en/main.json (1 hunks)
  • src/platform/assets/components/AssetFilterBar.vue (5 hunks)
  • src/platform/assets/composables/useAssetBrowser.ts (3 hunks)
  • src/platform/assets/fixtures/ui-mock-assets.ts (1 hunks)
  • tests-ui/platform/assets/components/AssetFilterBar.test.ts (1 hunks)
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts (5 hunks)
🧰 Additional context used
📓 Path-based instructions (16)
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively; no new JavaScript code

Files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
  • src/platform/assets/fixtures/ui-mock-assets.ts
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
  • src/platform/assets/composables/useAssetBrowser.ts
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,vue}: Use camelCase for variable and function names
Indent with 2 spaces (see .prettierrc)
Use single quotes for strings (see .prettierrc)
No trailing semicolons (see .prettierrc)
Maximum line width of 80 characters (see .prettierrc)
Sort and group imports by plugin (run pnpm format before committing)
Never use any type; use proper TypeScript types instead
Never use as any type assertions; fix the underlying type issue instead
Avoid code comments unless absolutely necessary; write expressive, self-documenting code instead
When writing new code, ask if there is a simpler way to introduce the same functionality; if yes, choose the simpler approach
Use refactoring to make complex code simpler
Use es-toolkit for utility functions
Use Vite for fast development and building
Implement proper error handling
Write tests for all changes, especially bug fixes to catch future regressions

Files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
  • src/platform/assets/fixtures/ui-mock-assets.ts
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
  • src/platform/assets/composables/useAssetBrowser.ts
  • src/platform/assets/components/AssetFilterBar.vue
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Avoid writing change detector tests that just assert default values
Avoid writing tests dependent on non-behavioral features like utility classes or styles
Avoid writing redundant tests

Files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/fixtures/ui-mock-assets.ts
  • src/platform/assets/composables/useAssetBrowser.ts
  • src/platform/assets/components/AssetFilterBar.vue
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/platform/assets/fixtures/ui-mock-assets.ts
  • src/platform/assets/composables/useAssetBrowser.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/assets/fixtures/ui-mock-assets.ts
  • src/platform/assets/composables/useAssetBrowser.ts
  • src/platform/assets/components/AssetFilterBar.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/assets/fixtures/ui-mock-assets.ts
  • src/platform/assets/composables/useAssetBrowser.ts
  • src/platform/assets/components/AssetFilterBar.vue
src/locales/**/*.json

📄 CodeRabbit inference engine (AGENTS.md)

Place new i18n translation entries in src/locales/en/main.json and use vue-i18n in Composition API for string literals

Files:

  • src/locales/en/main.json
**/composables/**/use*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables with useXyz.ts pattern

Files:

  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
  • src/platform/assets/composables/useAssetBrowser.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/assets/composables/useAssetBrowser.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/assets/composables/useAssetBrowser.ts
  • src/platform/assets/components/AssetFilterBar.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/assets/composables/useAssetBrowser.ts
  • src/platform/assets/components/AssetFilterBar.vue
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/assets/components/AssetFilterBar.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs with Composition API only (use <script setup lang="ts">, not Options API)
Avoid using <style> blocks; use Tailwind 4 for all styling
Use defineProps with TypeScript style default declaration; do not use withDefaults or runtime props declaration
Prefer useModel over separately defining a prop and emit
Use computed instead of a ref and watch if possible
Avoid using ref if a prop would accomplish the design goals; avoid using computed if a ref or prop directly would work
Do not import Vue macros unnecessarily
Never use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Never use :class="[]" to merge class names; always use cn() from @/utils/tailwindUtil (e.g., <div :class="cn('text-node-component-header-icon', hasError && 'text-danger')" />)
Leverage VueUse functions for performance-enhancing styles
Avoid new usage of PrimeVue components
Use Vue 3 Teleport component when needed
Use Vue 3 Suspense for async components

Files:

  • src/platform/assets/components/AssetFilterBar.vue
**/components/**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

Name Vue components in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/platform/assets/components/AssetFilterBar.vue
🧠 Learnings (16)
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Check assets/ directory for test data when writing tests

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.{ts,vue} : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.test.ts : Avoid writing change detector tests that just assert default values

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.test.ts : Avoid writing tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Use `computed` instead of a `ref` and `watch` if possible

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Avoid using `ref` if a prop would accomplish the design goals; avoid using `computed` if a `ref` or prop directly would work

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use setup() function for component logic

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabled

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Use Vue 3 SFCs with Composition API only (use `<script setup lang="ts">`, not Options API)

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
🧬 Code graph analysis (3)
tests-ui/platform/assets/components/AssetFilterBar.test.ts (1)
src/platform/assets/fixtures/ui-mock-assets.ts (1)
  • createAssetWithSpecificExtension (149-159)
tests-ui/platform/assets/composables/useAssetBrowser.test.ts (1)
src/platform/assets/composables/useAssetBrowser.ts (1)
  • useAssetBrowser (67-225)
src/platform/assets/composables/useAssetBrowser.ts (1)
src/platform/assets/schemas/assetSchema.ts (1)
  • AssetItem (73-73)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: deploy-and-comment
  • GitHub Check: test
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: collect
🔇 Additional comments (5)
tests-ui/platform/assets/components/AssetFilterBar.test.ts (2)

251-295: Ownership filter visibility tests match the intended UX

These tests correctly assert that the ownership control is:

  • Hidden when all assets are immutable,
  • Shown when any asset is mutable (including mixed sets).

Using the label === 'assetBrowser.ownership' filter makes the assertions robust against additional SingleSelect instances.


298-337: Good coverage of ownership emissions; consider extending the structure test

The new tests validate that:

  • Changing the ownership selector emits filterChange with the expected ownership value.
  • ownership defaults to 'all' when other filters (e.g., sort) change.

That’s solid coverage. As a small improvement, you could extend the existing “ensures FilterState interface compliance” test to also assert that typeof filterState.ownership === 'string' (and possibly that it’s defined), so it stays aligned when FilterState evolves.

⛔ Skipped due to learnings
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.{ts,vue} : Write tests for all changes, especially bug fixes to catch future regressions
tests-ui/platform/assets/composables/useAssetBrowser.test.ts (1)

381-463: Ownership filter behavior is well-covered in the composable tests

The new tests for:

  • 'all' (no filtering),
  • 'my-models' (!is_immutable),
  • 'public-models' (is_immutable),

nicely validate the core ownership logic in useAssetBrowser. They directly exercise the new ownership field in FilterState and confirm that the pipeline returns the expected asset counts and predicates.

src/platform/assets/components/AssetFilterBar.vue (1)

30-38: Ownership selector UI is wired correctly

The new SingleSelect for ownership:

  • Is gated by hasMutableAssets, matching the requirement to show it only when mutable assets exist.
  • Uses the new assetBrowser.ownership label and ownershipOptions.
  • Hooks into v-model="ownership" and @update:model-value="handleFilterChange" in line with the existing filters.

This is a good, minimal addition to the filter bar.

src/locales/en/main.json (1)

2139-2142: Ownership i18n keys correctly added and named

The new assetBrowser.ownership* keys are well‑named, concise, and match their usage in AssetFilterBar.vue and the ownership options. No issues here.

luke-mino-altherr and others added 4 commits December 6, 2025 13:27
Add dropdown to filter models by ownership (All/My models/Public models).
The filter only appears when user has uploaded models.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Change FilterState.ownership to use OwnershipOption literal union type
- Use strict comparison (=== false/true) for is_immutable checks
- Move type definitions before interface to follow dependency order

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Use findAllComponents with label filter to specifically find the sort
dropdown instead of the first SingleSelect, which could be the ownership
filter when mutable assets are present.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Pass allAssets to AssetFilterBar to check for mutable assets across all
categories, not just the currently filtered ones. This ensures the
ownership filter remains visible when switching categories, providing
better UX consistency.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@luke-mino-altherr luke-mino-altherr force-pushed the feat/model-modal-filter-by-ownership branch from 1dfba42 to 03791f7 Compare December 6, 2025 21:47
@github-actions
Copy link

github-actions bot commented Dec 6, 2025

🔧 Auto-fixes Applied

This PR has been automatically updated to fix linting and formatting issues.

⚠️ Important: Your local branch is now behind. Run git pull before making additional changes to avoid conflicts.

Changes made:

  • ESLint auto-fixes
  • Prettier formatting

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/platform/assets/composables/useAssetBrowser.ts (1)

38-45: Consider using stricter typing for the ownership parameter.

The filter logic is correct and handles undefined values properly with strict equality. However, the ownership parameter is typed as string rather than using the narrower type from FilterState['ownership'].

Apply this diff for improved type safety:

-function filterByOwnership(ownership: string) {
+function filterByOwnership(ownership: FilterState['ownership']) {
   return (asset: AssetItem) => {
     if (ownership === 'all') return true
     if (ownership === 'my-models') return asset.is_immutable === false
     if (ownership === 'public-models') return asset.is_immutable === true
     return true
   }
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1dfba42 and 03791f7.

📒 Files selected for processing (7)
  • src/locales/en/main.json (1 hunks)
  • src/platform/assets/components/AssetBrowserModal.vue (1 hunks)
  • src/platform/assets/components/AssetFilterBar.vue (4 hunks)
  • src/platform/assets/composables/useAssetBrowser.ts (3 hunks)
  • src/platform/assets/fixtures/ui-mock-assets.ts (1 hunks)
  • tests-ui/platform/assets/components/AssetFilterBar.test.ts (2 hunks)
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts (5 hunks)
🧰 Additional context used
📓 Path-based instructions (16)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/fixtures/ui-mock-assets.ts
  • src/platform/assets/components/AssetBrowserModal.vue
  • src/platform/assets/composables/useAssetBrowser.ts
  • src/platform/assets/components/AssetFilterBar.vue
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/platform/assets/fixtures/ui-mock-assets.ts
  • src/platform/assets/composables/useAssetBrowser.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/assets/fixtures/ui-mock-assets.ts
  • src/platform/assets/components/AssetBrowserModal.vue
  • src/platform/assets/composables/useAssetBrowser.ts
  • src/platform/assets/components/AssetFilterBar.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/assets/fixtures/ui-mock-assets.ts
  • src/platform/assets/components/AssetBrowserModal.vue
  • src/platform/assets/composables/useAssetBrowser.ts
  • src/platform/assets/components/AssetFilterBar.vue
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively; no new JavaScript code

Files:

  • src/platform/assets/fixtures/ui-mock-assets.ts
  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
  • src/platform/assets/composables/useAssetBrowser.ts
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,vue}: Use camelCase for variable and function names
Indent with 2 spaces (see .prettierrc)
Use single quotes for strings (see .prettierrc)
No trailing semicolons (see .prettierrc)
Maximum line width of 80 characters (see .prettierrc)
Sort and group imports by plugin (run pnpm format before committing)
Never use any type; use proper TypeScript types instead
Never use as any type assertions; fix the underlying type issue instead
Avoid code comments unless absolutely necessary; write expressive, self-documenting code instead
When writing new code, ask if there is a simpler way to introduce the same functionality; if yes, choose the simpler approach
Use refactoring to make complex code simpler
Use es-toolkit for utility functions
Use Vite for fast development and building
Implement proper error handling
Write tests for all changes, especially bug fixes to catch future regressions

Files:

  • src/platform/assets/fixtures/ui-mock-assets.ts
  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
  • src/platform/assets/components/AssetBrowserModal.vue
  • src/platform/assets/composables/useAssetBrowser.ts
  • src/platform/assets/components/AssetFilterBar.vue
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Avoid writing change detector tests that just assert default values
Avoid writing tests dependent on non-behavioral features like utility classes or styles
Avoid writing redundant tests

Files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/assets/components/AssetBrowserModal.vue
  • src/platform/assets/components/AssetFilterBar.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/assets/components/AssetBrowserModal.vue
  • src/platform/assets/composables/useAssetBrowser.ts
  • src/platform/assets/components/AssetFilterBar.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/assets/components/AssetBrowserModal.vue
  • src/platform/assets/composables/useAssetBrowser.ts
  • src/platform/assets/components/AssetFilterBar.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs with Composition API only (use <script setup lang="ts">, not Options API)
Avoid using <style> blocks; use Tailwind 4 for all styling
Use defineProps with TypeScript style default declaration; do not use withDefaults or runtime props declaration
Prefer useModel over separately defining a prop and emit
Use computed instead of a ref and watch if possible
Avoid using ref if a prop would accomplish the design goals; avoid using computed if a ref or prop directly would work
Do not import Vue macros unnecessarily
Never use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Never use :class="[]" to merge class names; always use cn() from @/utils/tailwindUtil (e.g., <div :class="cn('text-node-component-header-icon', hasError && 'text-danger')" />)
Leverage VueUse functions for performance-enhancing styles
Avoid new usage of PrimeVue components
Use Vue 3 Teleport component when needed
Use Vue 3 Suspense for async components

Files:

  • src/platform/assets/components/AssetBrowserModal.vue
  • src/platform/assets/components/AssetFilterBar.vue
**/components/**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

Name Vue components in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/platform/assets/components/AssetBrowserModal.vue
  • src/platform/assets/components/AssetFilterBar.vue
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/assets/composables/useAssetBrowser.ts
**/composables/**/use*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables with useXyz.ts pattern

Files:

  • src/platform/assets/composables/useAssetBrowser.ts
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
src/locales/**/*.json

📄 CodeRabbit inference engine (AGENTS.md)

Place new i18n translation entries in src/locales/en/main.json and use vue-i18n in Composition API for string literals

Files:

  • src/locales/en/main.json
🧠 Learnings (15)
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Check assets/ directory for test data when writing tests

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
  • tests-ui/platform/assets/composables/useAssetBrowser.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Prefer specific selectors in browser tests

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.{ts,vue} : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Use `computed` instead of a `ref` and `watch` if possible

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabled

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Use Vue 3 SFCs with Composition API only (use `<script setup lang="ts">`, not Options API)

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use setup() function for component logic

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.vue : Avoid using `ref` if a prop would accomplish the design goals; avoid using `computed` if a `ref` or prop directly would work

Applied to files:

  • src/platform/assets/components/AssetFilterBar.vue
🧬 Code graph analysis (3)
tests-ui/platform/assets/components/AssetFilterBar.test.ts (1)
src/platform/assets/fixtures/ui-mock-assets.ts (1)
  • createAssetWithSpecificExtension (149-159)
src/platform/assets/composables/useAssetBrowser.ts (1)
src/platform/assets/schemas/assetSchema.ts (1)
  • AssetItem (73-73)
tests-ui/platform/assets/composables/useAssetBrowser.test.ts (1)
src/platform/assets/composables/useAssetBrowser.ts (1)
  • useAssetBrowser (67-225)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: collect
🔇 Additional comments (18)
src/platform/assets/fixtures/ui-mock-assets.ts (1)

149-159: LGTM!

The optional isImmutable parameter cleanly extends the fixture helper to support ownership-related tests while maintaining backward compatibility with existing call sites.

src/platform/assets/components/AssetBrowserModal.vue (1)

49-53: LGTM!

Correctly passes the full asset set to AssetFilterBar via all-assets, enabling the ownership filter visibility check to operate on all fetched assets rather than just the category-filtered subset.

src/locales/en/main.json (1)

2139-2142: LGTM!

New i18n keys for the ownership filter are appropriately placed in the assetBrowser section and follow the existing camelCase naming convention.

src/platform/assets/composables/useAssetBrowser.ts (2)

74-79: LGTM!

The filter state correctly initializes ownership to 'all', ensuring all models are shown by default as specified in the PR objectives.


185-190: LGTM!

The ownership filter is correctly integrated into the filtering pipeline, applied after file format and base model filters, maintaining consistency with the existing filter chain pattern.

tests-ui/platform/assets/composables/useAssetBrowser.test.ts (4)

381-405: Test coverage for 'all' ownership is correct.

The test properly verifies that when ownership is set to 'all', all assets are returned regardless of their is_immutable state.


407-434: Good assertion pattern for 'my-models' filter.

The test correctly verifies both the count and that all returned assets have is_immutable === false (mutable assets).


436-463: Good assertion pattern for 'public-models' filter.

The test correctly verifies both the count and that all returned assets have is_immutable === true (immutable/public assets).


249-254: LGTM!

Existing tests correctly updated to include the new ownership field in filter updates.

tests-ui/platform/assets/components/AssetFilterBar.test.ts (3)

253-266: LGTM!

The test correctly verifies that the ownership filter is hidden when all assets are immutable.


268-297: LGTM!

These tests provide good coverage for ownership filter visibility with both mutable-only and mixed asset scenarios.


300-340: Comprehensive ownership filter behavior coverage.

These tests properly verify that ownership changes are emitted and that the default value is 'all'. The non-null assertion concern mentioned in the earlier comment also applies here.

src/platform/assets/components/AssetFilterBar.vue (6)

30-38: LGTM!

The ownership filter UI follows the established pattern for SingleSelect components and correctly uses conditional rendering based on hasMutableAssets.


59-59: LGTM!

The computed import is correctly added and necessary for the hasMutableAssets computed property.


78-86: LGTM!

The ownership options follow the same pattern as SORT_OPTIONS, providing excellent type safety with the derived OwnershipOption literal union type.


88-93: LGTM!

The FilterState interface correctly types ownership as OwnershipOption rather than a plain string, providing type safety for consumers. This addresses the past review feedback appropriately.


95-110: LGTM!

The implementation correctly:

  • Adds allAssets prop for visibility logic (separate from filtered assets)
  • Initializes ownership to 'all' as the default
  • Uses strict comparison (=== false) in hasMutableAssets to treat undefined/missing is_immutable as immutable

This addresses the past review feedback about explicit mutability checks.


120-121: LGTM!

The handleFilterChange function correctly includes ownership in the emitted filter state, maintaining consistency with the other filter fields.

luke-mino-altherr and others added 2 commits December 6, 2025 14:46
- Add explicit toBeTruthy() checks before using non-null assertions
  to provide clear error messages when components aren't found
- Move ownership filtering tests from 'Sorting' to dedicated
  'Ownership filtering' describe block for better organization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
The ownership filter visibility depends on the allAssets prop to
determine if mutable assets exist. Updated test cases to pass both
assets and allAssets props to properly test the ownership filter
functionality.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 71b8ca8 and dc25928.

📒 Files selected for processing (1)
  • tests-ui/platform/assets/components/AssetFilterBar.test.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively; no new JavaScript code

Files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,vue}: Use camelCase for variable and function names
Indent with 2 spaces (see .prettierrc)
Use single quotes for strings (see .prettierrc)
No trailing semicolons (see .prettierrc)
Maximum line width of 80 characters (see .prettierrc)
Sort and group imports by plugin (run pnpm format before committing)
Never use any type; use proper TypeScript types instead
Never use as any type assertions; fix the underlying type issue instead
Avoid code comments unless absolutely necessary; write expressive, self-documenting code instead
When writing new code, ask if there is a simpler way to introduce the same functionality; if yes, choose the simpler approach
Use refactoring to make complex code simpler
Use es-toolkit for utility functions
Use Vite for fast development and building
Implement proper error handling
Write tests for all changes, especially bug fixes to catch future regressions

Files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Avoid writing change detector tests that just assert default values
Avoid writing tests dependent on non-behavioral features like utility classes or styles
Avoid writing redundant tests

Files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
🧠 Learnings (10)
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Check assets/ directory for test data when writing tests

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.{ts,vue} : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Prefer specific selectors in browser tests

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.test.ts : Avoid writing change detector tests that just assert default values

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.test.ts : Avoid writing tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Avoid using ts-expect-error; use proper TypeScript types instead

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.test.ts : Avoid writing redundant tests

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.{ts,vue} : Never use `as any` type assertions; fix the underlying type issue instead

Applied to files:

  • tests-ui/platform/assets/components/AssetFilterBar.test.ts
🧬 Code graph analysis (1)
tests-ui/platform/assets/components/AssetFilterBar.test.ts (1)
src/platform/assets/fixtures/ui-mock-assets.ts (1)
  • createAssetWithSpecificExtension (149-159)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: test
  • GitHub Check: collect
🔇 Additional comments (1)
tests-ui/platform/assets/components/AssetFilterBar.test.ts (1)

108-112: Sort select lookup pattern looks solid

Finding the SingleSelect by its label and asserting its existence before emitting keeps the test robust against component order changes and avoids cryptic failures. The remaining non‑null assertion is acceptable here given the explicit expect.

Comment on lines +254 to +298
it('hides ownership filter when no mutable assets', () => {
const assets = [
createAssetWithSpecificExtension('safetensors', true) // immutable
]
const wrapper = mountAssetFilterBar({ assets })

const ownershipSelects = wrapper
.findAllComponents({ name: 'SingleSelect' })
.filter(
(component) => component.props('label') === 'assetBrowser.ownership'
)

expect(ownershipSelects).toHaveLength(0)
})

it('shows ownership filter when mutable assets exist', () => {
const assets = [
createAssetWithSpecificExtension('safetensors', false) // mutable
]
const wrapper = mountAssetFilterBar({ assets, allAssets: assets })

const ownershipSelects = wrapper
.findAllComponents({ name: 'SingleSelect' })
.filter(
(component) => component.props('label') === 'assetBrowser.ownership'
)

expect(ownershipSelects).toHaveLength(1)
})

it('shows ownership filter when mixed assets exist', () => {
const assets = [
createAssetWithSpecificExtension('safetensors', true), // immutable
createAssetWithSpecificExtension('ckpt', false) // mutable
]
const wrapper = mountAssetFilterBar({ assets, allAssets: assets })

const ownershipSelects = wrapper
.findAllComponents({ name: 'SingleSelect' })
.filter(
(component) => component.props('label') === 'assetBrowser.ownership'
)

expect(ownershipSelects).toHaveLength(1)
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Align allAssets usage in ownership visibility tests

The visibility tests correctly cover “no mutable”, “all mutable”, and “mixed” cases. For the “no mutable assets” case you only pass assets, while the other two pass both assets and allAssets. To better mirror real usage (where AssetBrowserModal always supplies allAssets) and make the intent explicit, consider also wiring allAssets there:

-      const wrapper = mountAssetFilterBar({ assets })
+      const wrapper = mountAssetFilterBar({ assets, allAssets: assets })

This keeps the test focused on “no mutable in the full asset set” rather than on the implicit defaulting behavior of allAssets.

🤖 Prompt for AI Agents
In tests-ui/platform/assets/components/AssetFilterBar.test.ts around lines 254
to 298, the first test ("hides ownership filter when no mutable assets") only
passes assets but not allAssets, making it rely on implicit defaulting; update
that test to pass allAssets: assets (i.e., mountAssetFilterBar({ assets,
allAssets: assets })) so the test explicitly mirrors real usage where
AssetBrowserModal supplies allAssets and verifies there are no mutable assets in
the full set.

Comment on lines +301 to +342
describe('Ownership Filter', () => {
it('emits ownership filter changes', async () => {
const assets = [
createAssetWithSpecificExtension('safetensors', false) // mutable
]
const wrapper = mountAssetFilterBar({ assets, allAssets: assets })

const ownershipSelect = wrapper
.findAllComponents({ name: 'SingleSelect' })
.find(
(component) => component.props('label') === 'assetBrowser.ownership'
)

expect(ownershipSelect).toBeTruthy()
await ownershipSelect!.vm.$emit('update:modelValue', 'my-models')
await nextTick()

const emitted = wrapper.emitted('filterChange')
expect(emitted).toHaveLength(1)

const filterState = emitted![0][0] as FilterState
expect(filterState.ownership).toBe('my-models')
})

it('ownership filter defaults to "all"', async () => {
const assets = [
createAssetWithSpecificExtension('safetensors', false) // mutable
]
const wrapper = mountAssetFilterBar({ assets })

const sortSelect = wrapper
.findAllComponents({ name: 'SingleSelect' })
.find((component) => component.props('label') === 'assetBrowser.sortBy')

expect(sortSelect).toBeTruthy()
await sortSelect!.vm.$emit('update:modelValue', 'recent')
await nextTick()

const emitted = wrapper.emitted('filterChange')
const filterState = emitted![0][0] as FilterState
expect(filterState.ownership).toBe('all')
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Ownership behavior tests are good; consider small consistency tweaks

The new tests correctly assert that ownership changes propagate into filterChange and that ownership defaults to 'all' when only sort changes. Two optional polish points:

  • In the default test, also assert the emitted length for symmetry and clearer failures:
-      const emitted = wrapper.emitted('filterChange')
-      const filterState = emitted![0][0] as FilterState
+      const emitted = wrapper.emitted('filterChange')
+      expect(emitted).toHaveLength(1)
+      const filterState = emitted![0][0] as FilterState
  • Optionally pass allAssets: assets in the default test as well to match production wiring, though behavior here doesn’t currently depend on it.

These are minor and non‑blocking; behavior under test is covered well. Based on learnings, this keeps tests behavior‑focused rather than relying on incidental defaults.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
describe('Ownership Filter', () => {
it('emits ownership filter changes', async () => {
const assets = [
createAssetWithSpecificExtension('safetensors', false) // mutable
]
const wrapper = mountAssetFilterBar({ assets, allAssets: assets })
const ownershipSelect = wrapper
.findAllComponents({ name: 'SingleSelect' })
.find(
(component) => component.props('label') === 'assetBrowser.ownership'
)
expect(ownershipSelect).toBeTruthy()
await ownershipSelect!.vm.$emit('update:modelValue', 'my-models')
await nextTick()
const emitted = wrapper.emitted('filterChange')
expect(emitted).toHaveLength(1)
const filterState = emitted![0][0] as FilterState
expect(filterState.ownership).toBe('my-models')
})
it('ownership filter defaults to "all"', async () => {
const assets = [
createAssetWithSpecificExtension('safetensors', false) // mutable
]
const wrapper = mountAssetFilterBar({ assets })
const sortSelect = wrapper
.findAllComponents({ name: 'SingleSelect' })
.find((component) => component.props('label') === 'assetBrowser.sortBy')
expect(sortSelect).toBeTruthy()
await sortSelect!.vm.$emit('update:modelValue', 'recent')
await nextTick()
const emitted = wrapper.emitted('filterChange')
const filterState = emitted![0][0] as FilterState
expect(filterState.ownership).toBe('all')
})
describe('Ownership Filter', () => {
it('emits ownership filter changes', async () => {
const assets = [
createAssetWithSpecificExtension('safetensors', false) // mutable
]
const wrapper = mountAssetFilterBar({ assets, allAssets: assets })
const ownershipSelect = wrapper
.findAllComponents({ name: 'SingleSelect' })
.find(
(component) => component.props('label') === 'assetBrowser.ownership'
)
expect(ownershipSelect).toBeTruthy()
await ownershipSelect!.vm.$emit('update:modelValue', 'my-models')
await nextTick()
const emitted = wrapper.emitted('filterChange')
expect(emitted).toHaveLength(1)
const filterState = emitted![0][0] as FilterState
expect(filterState.ownership).toBe('my-models')
})
it('ownership filter defaults to "all"', async () => {
const assets = [
createAssetWithSpecificExtension('safetensors', false) // mutable
]
const wrapper = mountAssetFilterBar({ assets })
const sortSelect = wrapper
.findAllComponents({ name: 'SingleSelect' })
.find((component) => component.props('label') === 'assetBrowser.sortBy')
expect(sortSelect).toBeTruthy()
await sortSelect!.vm.$emit('update:modelValue', 'recent')
await nextTick()
const emitted = wrapper.emitted('filterChange')
expect(emitted).toHaveLength(1)
const filterState = emitted![0][0] as FilterState
expect(filterState.ownership).toBe('all')
})
🤖 Prompt for AI Agents
In tests-ui/platform/assets/components/AssetFilterBar.test.ts around lines 301
to 342, add a check in the "ownership filter defaults to 'all'" test to assert
the number of emitted 'filterChange' events (e.g.,
expect(emitted).toHaveLength(1)) for symmetry with the other test and clearer
failures, and optionally pass allAssets: assets into mountAssetFilterBar(...) to
mirror production wiring; update the test to capture emitted, assert its length,
then assert filterState.ownership === 'all'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:models enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants